/*
    文件内容: 封装Epoll相关操作类
    文件名: Epoll.h
    作者: 中国好青年(码农论坛)
    时间: 2024/9/6

*/
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <vector>
#include "Channel.h"

/*
    /*
    类名: EPOLL_TYPE
    作用: 封装Epoll一些时间枚举值
*/
typedef enum{
    /* The associated file is available for read(2) operations. */
    EPOLL_IN = EPOLLIN,
    /* The associated file is available for write(2) operations. */ 
    EPOLL_RDHUP = EPOLLRDHUP,
             
    /* Stream socket peer closed connection, or shut down writing half of connection.  (This flag  is  especially  useful
       for writing simple code to detect peer shutdown when using Edge Triggered monitoring.) */
    EPOLL_PRI = EPOLLPRI,

    /* There is urgent data available for read(2) operations. */
    EPOLL_ERR = EPOLLERR,

    /* Error  condition happened on the associated file descriptor.  epoll_wait(2) will always wait for this event; it is
       not necessary to set it in events. */
    EPOLL_HUP = EPOLLHUP,

    /* Hang up happened on the associated file descriptor.  epoll_wait(2) will always wait for this event; it is not nec‐
       essary to set it in events. */
    EPOLL_ET = EPOLLET,

    /* Sets  the  Edge  Triggered  behavior  for the associated file descriptor.  The default behavior for epoll is Level
       Triggered.  See epoll(7) for more detailed information about Edge and Level Triggered event distribution architec‐
       tures. */
    EPOLL_ONESHOT  = EPOLLONESHOT
}EPOLL_TYPE;

/* 前置声明类 */
class Channel;

/*
    类名: Epoll
    作用: 封装Epoll相关操作类
*/
class Epoll
{
private:
    //事件发生数组的大小
    static const int MAX_EVENTS = 100;
    //epollfd 和 epoll_wait数组
    int epollfd_ = -1;
    struct epoll_event events_[MAX_EVENTS];
public:
    /* 构造函数 和 析构函数 */
    Epoll();
    ~Epoll();

    /* Epoll相关操作函数 */
    void updateChannel(Channel* ch);
    void removeChannel(Channel* ch);
    std::vector<Channel*> loop(int timeout = -1);
};